#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
练习题 21: 装饰器工厂
难度: ⭐⭐
知识点: 装饰器设计、闭包、函数式编程
参考文件: comparison_examples/advanced/05_decorators.py
"""

import time
import functools
from typing import Callable, Any

def problem_description():
    """
    题目描述:
    设计一个装饰器工厂系统，能够创建各种功能的装饰器。
    
    要求:
    1. 实现计时装饰器工厂
    2. 实现重试装饰器工厂
    3. 实现日志装饰器工厂
    4. 实现参数验证装饰器工厂
    5. 实现缓存装饰器工厂
    
    装饰器特性:
    - 支持参数配置
    - 保留原函数的元信息
    - 支持同步和异步函数
    - 提供详细的错误信息
    """
    pass

# TODO: 实现以下装饰器工厂

def timer(unit='seconds', precision=4):
    """
    计时装饰器工厂
    
    Args:
        unit (str): 时间单位 ('seconds', 'milliseconds', 'microseconds')
        precision (int): 精度（小数位数）
    
    Returns:
        function: 装饰器函数
    
    示例:
        @timer(unit='milliseconds', precision=2)
        def slow_function():
            time.sleep(0.1)
            return "完成"
    """
    # 在这里实现你的代码
    pass

def retry(max_attempts=3, delay=1, backoff=1, exceptions=(Exception,)):
    """
    重试装饰器工厂
    
    Args:
        max_attempts (int): 最大重试次数
        delay (float): 初始延迟时间（秒）
        backoff (float): 延迟倍数
        exceptions (tuple): 需要重试的异常类型
    
    Returns:
        function: 装饰器函数
    
    示例:
        @retry(max_attempts=3, delay=0.5, backoff=2)
        def unreliable_function():
            import random
            if random.random() < 0.7:
                raise ConnectionError("网络错误")
            return "成功"
    """
    # 在这里实现你的代码
    pass

def logger(level='INFO', format_string=None, include_args=True, include_result=True):
    """
    日志装饰器工厂
    
    Args:
        level (str): 日志级别
        format_string (str): 自定义格式字符串
        include_args (bool): 是否包含参数信息
        include_result (bool): 是否包含返回值信息
    
    Returns:
        function: 装饰器函数
    
    示例:
        @logger(level='DEBUG', include_args=True, include_result=True)
        def calculate(x, y):
            return x + y
    """
    # 在这里实现你的代码
    pass

def validate(*validators):
    """
    参数验证装饰器工厂
    
    Args:
        *validators: 验证函数列表
    
    Returns:
        function: 装饰器函数
    
    示例:
        def positive_number(x):
            if x <= 0:
                raise ValueError("数字必须为正数")
            return True
        
        @validate(positive_number)
        def sqrt(x):
            return x ** 0.5
    """
    # 在这里实现你的代码
    pass

def cache(maxsize=128, ttl=None):
    """
    缓存装饰器工厂
    
    Args:
        maxsize (int): 最大缓存大小
        ttl (float): 缓存生存时间（秒），None表示永不过期
    
    Returns:
        function: 装饰器函数
    
    示例:
        @cache(maxsize=100, ttl=60)
        def expensive_calculation(n):
            time.sleep(1)  # 模拟耗时计算
            return n * n
    """
    # 在这里实现你的代码
    pass

def rate_limit(calls_per_second=1):
    """
    限流装饰器工厂
    
    Args:
        calls_per_second (float): 每秒允许的调用次数
    
    Returns:
        function: 装饰器函数
    
    示例:
        @rate_limit(calls_per_second=2)
        def api_call():
            return "API响应"
    """
    # 在这里实现你的代码
    pass

def deprecated(reason="", version="", alternative=""):
    """
    弃用警告装饰器工厂
    
    Args:
        reason (str): 弃用原因
        version (str): 弃用版本
        alternative (str): 替代方案
    
    Returns:
        function: 装饰器函数
    
    示例:
        @deprecated(reason="性能问题", version="2.0", alternative="new_function")
        def old_function():
            return "旧功能"
    """
    # 在这里实现你的代码
    pass

# 辅助函数和类

class DecoratorChain:
    """
    装饰器链，允许组合多个装饰器
    
    示例:
        chain = DecoratorChain()
        chain.add(timer())
        chain.add(retry(max_attempts=2))
        chain.add(logger())
        
        @chain.apply
        def my_function():
            return "结果"
    """
    
    def __init__(self):
        self.decorators = []
    
    def add(self, decorator):
        """添加装饰器到链中"""
        # 在这里实现你的代码
        pass
    
    def apply(self, func):
        """应用装饰器链到函数"""
        # 在这里实现你的代码
        pass

def demonstrate_decorator_factory():
    """
    演示装饰器工厂的功能
    """
    print("=== 装饰器工厂演示 ===")
    
    # 计时装饰器演示
    print("\n=== 计时装饰器 ===")
    
    @timer(unit='milliseconds', precision=2)
    def slow_task():
        time.sleep(0.1)
        return "任务完成"
    
    result = slow_task()
    print(f"结果: {result}")
    
    # 重试装饰器演示
    print("\n=== 重试装饰器 ===")
    
    attempt_count = 0
    
    @retry(max_attempts=3, delay=0.1, backoff=1)
    def unreliable_task():
        nonlocal attempt_count
        attempt_count += 1
        if attempt_count < 3:
            raise ConnectionError(f"第{attempt_count}次尝试失败")
        return "最终成功"
    
    try:
        result = unreliable_task()
        print(f"结果: {result}")
    except Exception as e:
        print(f"最终失败: {e}")
    
    # 日志装饰器演示
    print("\n=== 日志装饰器 ===")
    
    @logger(level='INFO', include_args=True, include_result=True)
    def calculate_sum(a, b):
        return a + b
    
    result = calculate_sum(10, 20)
    
    # 参数验证装饰器演示
    print("\n=== 参数验证装饰器 ===")
    
    def is_positive(x):
        if x <= 0:
            raise ValueError("参数必须为正数")
        return True
    
    @validate(is_positive)
    def square_root(x):
        return x ** 0.5
    
    try:
        result = square_root(16)
        print(f"√16 = {result}")
        result = square_root(-4)  # 这会引发异常
    except ValueError as e:
        print(f"验证失败: {e}")
    
    # 缓存装饰器演示
    print("\n=== 缓存装饰器 ===")
    
    @cache(maxsize=10, ttl=5)
    def fibonacci(n):
        if n <= 1:
            return n
        return fibonacci(n-1) + fibonacci(n-2)
    
    start_time = time.time()
    result1 = fibonacci(10)
    time1 = time.time() - start_time
    
    start_time = time.time()
    result2 = fibonacci(10)  # 从缓存获取
    time2 = time.time() - start_time
    
    print(f"第一次计算: {result1}, 耗时: {time1:.4f}秒")
    print(f"第二次计算: {result2}, 耗时: {time2:.4f}秒")
    
    # 装饰器链演示
    print("\n=== 装饰器链 ===")
    
    chain = DecoratorChain()
    chain.add(timer(unit='milliseconds'))
    chain.add(logger(level='DEBUG'))
    
    @chain.apply
    def complex_task(x, y):
        time.sleep(0.05)
        return x * y
    
    result = complex_task(5, 6)
    print(f"链式装饰器结果: {result}")

if __name__ == "__main__":
    # 运行演示
    demonstrate_decorator_factory()
    
    print("\n=== 装饰器最佳实践 ===")
    print("1. 使用 functools.wraps 保留原函数元信息")
    print("2. 装饰器应该是幂等的")
    print("3. 考虑装饰器的组合和顺序")
    print("4. 提供清晰的错误信息")
    print("5. 文档化装饰器的行为和副作用")
